Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support JPEG compression #583

Merged
merged 4 commits into from
Feb 5, 2025
Merged

Support JPEG compression #583

merged 4 commits into from
Feb 5, 2025

Conversation

vmobilis
Copy link
Contributor

@vmobilis vmobilis commented Feb 2, 2025

  1. implement jpeg comment block to save parameters of generation;
  2. save output with jpeg compression when extension is .jpg.

JPEG quality is simply set to 90, to not complicate command options.

And thanks for the program! 🙂

stbiw__putc(s, param_length >> 8); // no need to mask, length < 65536
stbiw__putc(s, param_length & 0xFF);
s->func(s->context, (void*)"parameters", strlen("parameters") + 1); // std::string is zero-terminated
s->func(s->context, (void*)parameters, param_length - 2 - strlen("parameters") - 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be missing a zero-termination for parameters with length above 65522 (0xFFFF - strlen("parameters") - 1 - 1)

Copy link
Contributor Author

@vmobilis vmobilis Feb 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@idostyle, thanks for review.
JPEG comment block:
comment_marker { 0xFF, 0xFE /* comment marker */ }
comment_body {
  uint16be comment_body.length(),
  "comment" /* std::string terminates with 0 for compatibility with C strings */
}

Comment length can be 2..65535 bytes, according to https://www.w3.org/Graphics/JPEG/itu-t81.pdf, "Table B.8 – Comment segment parameter sizes and values".

     size_t param_length = std::min(2 + strlen("parameters") + 1 + strlen(parameters) + 1, (size_t) 0xFFFF);

// maker_length + len('parameters') + 0 + params.length() + 0,
// truncated to 65535 bytes, so comment can be 65535 - 2 - 10 - 1 - 1 = 65521 bytes.

     s->func(s->context, (void*)parameters, param_length - 2 - strlen("parameters") - 1);

// 65535 - 2 /* marker*/ - 10 - 1 /* 'parameters' + 0 */

Second 0, terminating params, is not substracted, therefore it will be written.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@idostyle, I finally got it, you're right, despite that length of comment block is limited, it should always be terminated with 0, for safety. Fixed.

@stduhpf
Copy link
Contributor

stduhpf commented Feb 2, 2025

Nice. I'm surprised stb_image doesn't support metadata by default.

@leejet leejet merged commit d46ed5e into leejet:master Feb 5, 2025
8 checks passed
@leejet
Copy link
Owner

leejet commented Feb 5, 2025

Thank you for your contribution.

stduhpf pushed a commit to stduhpf/stable-diffusion.cpp that referenced this pull request Feb 8, 2025
@vmobilis vmobilis deleted the patch-1 branch February 9, 2025 04:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants